package benchmarks.benchmarktests;

import helpers.IAction;
import helpers.RaceConditionException;
import helpers.SafeCounter;
import problems.producerconsumer.AbstractProducerConsumer;

public class ProducerConsumerTest extends BenchmarkTest<AbstractProducerConsumer> {
	private int nbThreads;
	private int expectedCount = 0;
	private final SafeCounter counter = new SafeCounter(0);

	public ProducerConsumerTest(AbstractProducerConsumer solution, int nbThreads) {
		super(solution);
		this.nbThreads = nbThreads;
	}

	@Override
	public Thread[] InitializeThreads() {
        Thread[] initializedThreads = new Thread[nbThreads * 2];
        
        for (int i = 0; i < nbThreads; i++)
        {
            initializedThreads[i] = new Thread() {
            	public void run() {
            		solution.consume();
            	}
            };
            final int j = i;
            initializedThreads[i + nbThreads] = new Thread() {
            	public void run() {
            		solution.produce(new IAction() {
            			public void invoke() {
            				counter.add(j);
            			}
            		});
            	}
            };
            expectedCount += j;
        }
        
		return initializedThreads;
	}
	
	@Override
	public void runAdditionalTests() {
        if (counter.getCount() != expectedCount) 
        	throw new RaceConditionException(counter.getCount() + " != " + expectedCount);
	}

}
